using System;
using System.Collections.Generic;
using System.Text;

namespace Serialization
{
    class ObjectIDGenerator
    {
        private ObjectIDDictionary _objectMap = new ObjectIDDictionary();
        private long _currentId = 1L;

        public void Reset()
        {
            _objectMap.Clear();
            _currentId = 1L;
        }

        public long GetId(object obj, out bool firstTime)
        {
            long id;
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (firstTime = !_objectMap.TryGetValue(obj, out id))
            {
                long t;
                _currentId = (t = _currentId) + 1L;
                id = t;
                _objectMap.Add(obj, id);
            }
            return id;
        }

        public long HasId(object obj, out bool firstTime)
        {
            long id;
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (firstTime = !_objectMap.TryGetValue(obj, out id))
            {
                id = 0L;
            }
            return id;
        }

        private class ObjectIDDictionary : Dictionary<object, long>
        {
            public ObjectIDDictionary()
                : base(new ObjectIDEqualityComparer())
            {
            }

            private class ObjectIDEqualityComparer : IEqualityComparer<object>
            {
                #region IEqualityComparer<object> Members

                bool IEqualityComparer<object>.Equals(object x, object y)
                {
                    if (x is string)
                    {
                        return x.Equals(y);
                    }
                    return x == y;
                }

                int IEqualityComparer<object>.GetHashCode(object obj)
                {
                    return obj.GetHashCode();
                }

                #endregion
            }
        }
    }
}
